package com.xc.pay.weixin.util;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.xc.pay.common.MessageTemplate;
import com.xc.pay.weixin.enums.VersionEnum;
import com.xc.pay.weixin.enums.WxPayTypeEnum;
import com.xc.pay.weixin.properties.base.WxPayBaseProperties;
import com.xc.pay.weixin.properties.base.WxPayCommonProperties;
import com.xc.pay.weixin.template.Base.WxPayTemplateClient;
import com.xc.pay.weixin.template.WxPayAppTemplate;
import com.xc.pay.weixin.template.WxPayJsApiTemplate;

import java.util.Objects;

/**
 * 支付模板工具
 *
 * @author rongrong
 * @date 2020/12/2
 */
public class WxPayTemplateUtil {

  /**
   * 检出所需对象
   *
   * @param properties 属性
   * @return template
   */
  public WxPayTemplateClient checkObj(
      WxPayBaseProperties properties, VersionEnum version, WxPayTypeEnum typeEnum) {
    // 校验
    checkVersion(properties, version);
    // 控制版本参数校验
    switch (version) {
      case V2:
        break;
      case V3:
        return v3Template(properties, typeEnum);
      default:
        return null;
    }
    return null;
  }

  /**
   * 如果common有值则设置进入模板属性类 优先考虑properties下属性
   *
   * @param properties 属性
   * @param commonProperties 公共属性
   */
  public void isCommonSetProperties(
      WxPayBaseProperties properties, WxPayCommonProperties commonProperties) {
    if (Objects.nonNull(commonProperties)) {
      final String apiV3Key = commonProperties.getApiV3Key();
      if (StrUtil.isNotBlank(apiV3Key) && StrUtil.isBlank(properties.getApiV3Key())) {
        properties.setApiV3Key(apiV3Key);
      }
      final String serialNumber = commonProperties.getCertSerialNumber();
      if (StrUtil.isNotBlank(serialNumber) && StrUtil.isBlank(properties.getCertSerialNumber())) {
        properties.setCertSerialNumber(serialNumber);
      }
      final String keyPath = commonProperties.getKeyPath();
      if (StrUtil.isNotBlank(keyPath) && StrUtil.isBlank(properties.getKeyPath())) {
        properties.setKeyPath(keyPath);
      }
      final String mchid = commonProperties.getMchid();
      if (StrUtil.isNotBlank(mchid) && StrUtil.isBlank(properties.getMchid())) {
        properties.setMchid(mchid);
      }
      final String mchKey = commonProperties.getMchKey();
      if (StrUtil.isNotBlank(mchKey) && StrUtil.isBlank(properties.getMchKey())) {
        properties.setMchKey(mchKey);
      }
      final String privateCertPath = commonProperties.getPrivateCertPath();
      if (StrUtil.isNotBlank(privateCertPath) && StrUtil.isBlank(properties.getPrivateCertPath())) {
        properties.setPrivateCertPath(privateCertPath);
      }
      final String privateKeyPath = commonProperties.getPrivateKeyPath();
      if (StrUtil.isNotBlank(privateKeyPath) && StrUtil.isBlank(properties.getPrivateKeyPath())) {
        properties.setPrivateKeyPath(privateKeyPath);
      }
    }
  }

  /**
   * V3版本Template
   *
   * @param properties 属性
   * @param type 类型
   * @return WxPayBaseTemplate 模板配置类
   */
  private WxPayTemplateClient v3Template(WxPayBaseProperties properties, WxPayTypeEnum type) {
    final String privateKeyPath = properties.getPrivateKeyPath();
    final String privateCertPath = properties.getPrivateCertPath();
    final String certSerialNumber = properties.getCertSerialNumber();
    final String apiV3Key = properties.getApiV3Key();
    final String mchid = properties.getMchid();
    // 初始化对应template
    final WxPayTemplateClient template = choiceObj(type, properties);
    assert template != null;
    template.build(privateKeyPath, privateCertPath, certSerialNumber, apiV3Key, mchid);
    return template;
  }

  /**
   * 根据配置类型选择对应Obj
   *
   * @param type 支付类型
   * @param properties 配置
   * @return 支付template 父类
   */
  private WxPayTemplateClient choiceObj(WxPayTypeEnum type, WxPayBaseProperties properties) {
    WxPayTemplateClient template = null;
    switch (type) {
      case PAYMENT_CODE:
      case MINI_PROGRAM:
      case NATIVEPAY:
      case H5:
      case JSAPI:
        template = new WxPayJsApiTemplate();
        break;
      case APP:
        template = new WxPayAppTemplate();
        break;
      default:
        break;
    }
    template.setProperties(properties);
    return template;
  }

  /**
   * 版本选择判断参数
   *
   * @param properties 属性类
   * @param version 版本号
   */
  private void checkVersion(WxPayBaseProperties properties, VersionEnum version) {
    // 参数校验
    final String appid = properties.getAppid();
    Assert.notBlank(appid, MessageTemplate.ERROR_TEMPLATE, "appid");
    final String mchId = properties.getMchid();
    Assert.notBlank(mchId, MessageTemplate.ERROR_TEMPLATE, "mchid");
    final String mchKey = properties.getMchKey();
    Assert.notBlank(mchKey, MessageTemplate.ERROR_TEMPLATE, "mchKey");
    // 控制版本参数校验
    switch (version) {
      case V2:
        break;
      case V3:
        WxToolUtil.checkArgs(properties);
        break;
      default:
        throw new IllegalArgumentException("版本号错误");
    }
  }
}
